package WorkflowService

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"seawolf-admin-go/internal/model/workflowEntity"
	"seawolf-admin-go/internal/request/WorkflowReq"
	"seawolf-admin-go/internal/service/BaseService"
	"seawolf-admin-go/utility/db"
	"sync"
	"time"
)

var saveLock sync.Mutex

func SaveProcessDefReq(ctx context.Context, req *WorkflowReq.ProcessAdd, oldProcdefId int64) (id int64, err error) {
	// 流程定义有效性检验
	//err = CheckProcessConifgIsValid(req.Resource)
	//if err != nil {
	//	return 0, err
	//}
	//解析成字符串
	result, err := json.Marshal(req.Resource)
	if err != nil {
		return 0, err
	}
	resource := fmt.Sprintf("%s", result)
	model := &workflowEntity.Procdef{
		Name: req.Name,
		//Userid:   req.Userid,
		//Username: req.Username,
		Company:  "zk",
		Resource: resource,
	}
	model.Version = 1
	//model.DeployTime = gtime.Now().Format("Y_m_d_H_i_s")
	model.CreateAt = time.Now().Unix()
	//model.UpdateAt = gconv.Int(time.Now().Unix())
	model.DeleteAt = 0
	fmt.Printf("%+v", &model)
	saveLock.Lock()
	defer saveLock.Unlock()
	// 添加
	if oldProcdefId == 0 {
		return saveNewAdd(ctx, model)
	}
	//查询
	oldModel, err := GetProcdefById(ctx, oldProcdefId)
	if oldModel == nil {
		return 0, err
	}
	// 保存新版本
	model.Version = oldModel.Version + 1
	return saveUpdate(ctx, model, oldModel)
}

// 新增时保存
func saveNewAdd(ctx context.Context, p *workflowEntity.Procdef) (int64, error) {
	//表名
	tableName := "procdef"
	//查询是否已经存在
	var count int
	//func (m *Model) Count(where ...interface{}) (int, error)
	count, err := db.GetUnSafaTable(ctx, tableName).Where("name=? and resource=? and company=?", p.Name, p.Resource, p.Company).
		Handler(db.SoftDeleteHandler).Count()
	if err != nil {
		return 0, nil
	}
	if count > 0 {
		return 0, errors.New("流程定义【" + fmt.Sprintf("%s", p.Name) + "】已经存在")
	}
	//插入
	res, err := db.GetUnSafaTable(ctx, tableName).Insert(p)
	if err != nil {
		return 0, err
	}
	id, err := res.LastInsertId()
	if err != nil {
		return 0, err
	}
	// 尝试删除缓存
	BaseService.HandleBaseCache(ctx, tableName)
	return id, err
}

// 修改时保存
func saveUpdate(ctx context.Context, p *workflowEntity.Procdef, oldModel *workflowEntity.Procdef) (int64, error) {
	tx, err := g.DB().Begin(ctx)
	if err == nil {
		fmt.Println("开启事务操作")
	} else {
		return 0, err
	}
	//表名
	tableName := "procdef"
	result, err2 := tx.Ctx(ctx).Insert(tableName, p)
	if err2 != nil {
		tx.Rollback()
		return 0, err2
	}
	// user_detail
	id, err := result.LastInsertId()
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	// 转移旧版本
	//_, err = tx.Ctx(ctx).Exec("insert into sw_procdef_history select * from sw_procdef where id=?", oldId)
	_, err = tx.Ctx(ctx).Insert("sw_procdef_history", g.Map{
		"id":        oldModel.Id,
		"name":      oldModel.Name,
		"version":   oldModel.Version,
		"resource":  oldModel.Resource,
		"userid":    oldModel.Userid,
		"username":  oldModel.Username,
		"company":   oldModel.Company,
		"create_at": oldModel.CreateAt,
		"update_at": time.Now().Unix(),
		"delete_at": 0,
		"new_id":    id,
	})
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	// 删除
	_, err = tx.Ctx(ctx).Delete(tableName, "id=?", oldModel.Id)
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	tx.Commit()
	// 尝试删除缓存
	BaseService.HandleBaseCache(ctx, tableName)
	return id, err
}

// 根据流程定义id获取流程定义 没有则抛出错误
func GetProcdefById(ctx context.Context, id int64) (out *workflowEntity.Procdef, err error) {
	//var p = &entity.Procdef{}
	//ORM最佳实践 - GoFrame
	//https://goframe.org/pages/viewpage.action?pageId=54110796
	err = db.GetUnSafaTable(ctx, "procdef").Where("id", id).Handler(db.SoftDeleteHandler).Scan(&out)
	if out == nil {
		err = gerror.Newf(`procdef record not found for "%d"`, id)
	}
	return out, err
}
